package tec ;
 /**
 * Réalisation d'un Autobus.
 * La classe Autobus realise le service de trajet d'arret en arret d'un transport 
 * et controle le comportement (changement d'état) de ses passagers.
 *
 * Le client declenche le trajet vers un nouvel arret par la methode allerArretSuivant().
 *
 * Un autobus a un nombre determine de places assises et de places debouts. 
 * Les places assises (ou debout) ne sont pas reperables. Les nombres de place 
 * assise et bebout sont fixes a l'instanciation .
 *
 * Le code d'autobus n'effectue jamais de vérification sur le nombre 
 * disponible de place assises ou debout.
 *
 * Un autobus authorise un passager a entrer pour occuper soit une place debout soit 
 * une place assise Si l'entree est acceptee l'autobus declenche les modificateurs 
 * de passager (changement de l'etat du passager).
 *
 * Le transport previent ses passagers de chaque nouvel arret par appel a la mzthode 
 * nouvelArret() sur chaque passager.
 * 
 * A chaque arret, un autobus permet aux passagers de l'autobus soit de sortir, 
 * soit de changer de place (d'assise en debout, ou l'inverse). Si la demande est acceptee, 
 * l'autobus declenche les méthode de modification de l'état du passager. 
 * Les instances de cette classe implémente les interfaces Bus 
 * et Transport.
 * @author georgy * @since 2011-2012
 **/



class Autobus implements Bus, Transport
{
    private JaugeNaturel jaugeAssis;
    private JaugeNaturel jaugeDebout;
    private Passager[] passagers;
    private int nbPassagers ;
    private int numeroArret = 0;
	
    protected Autobus(int nbPlaceAssise, int nbPlaceDebout)
    {

	jaugeAssis  = new JaugeNaturel(0, nbPlaceAssise, 0);
	jaugeDebout = new JaugeNaturel(0, nbPlaceDebout, 0);

        nbPassagers = 0;
        passagers = new Passager[nbPlaceAssise + nbPlaceDebout];
    }
    
    
    
    
    
   /**
   * Le passager est-il a l'intérieur du transport ?
   *
   * @return vrai si instanciation avec ASSIS ou DEBOUT.
   */
    public void allerArretSuivant(){
       numeroArret++;
       /*Parcours du tableau à l'envers pour éviter les conflits
        * lors de la decsente (suppresion d'un passager
        */
       for(int i = nbPassagers-1 ; i >= 0 ; i--)
       {
          passagers[i].nouvelArret(this,numeroArret);
       }
    
    }
    
    
    
    
   /**
   * Le bus dispose t'il de places assises libres ?
   *
   * @return vrai si places assises disponibles (JaugeAssis de couleur différente du rouge).
   */
    public boolean aPlaceAssise()
    {
	return (!jaugeAssis.estRouge()); 
    }
    


   /**
   * Le bus dispose t'il de places debout libre ?
   *
   * @return vrai si places debout disponibles (JaugeAssis de couleur différente du rouge).
   */
    public boolean aPlaceDebout()
    {
	return (!jaugeDebout.estRouge());
    }	    
	
	
	
   /**
   * Change un passager d'une place debout vers une place assise. 
   * Elle change l'etat du passager. 
   * @param le passager 
   *
   */
    public void demanderChangerEnAssis(Passager p)
    { 
          p.accepterPlaceAssise();
          jaugeAssis.incrementer();
          jaugeDebout.decrementer();
    }




   /**
   * Change un passager d'une place assise vers une place debout.
   * Elle change l'etat du passager. 
   * @param le passager 
   */   
    public void demanderChangerEnDebout(Passager p)
    { 
          p.accepterPlaceDebout();
          jaugeAssis.decrementer();
          jaugeDebout.incrementer();
          
    }




   /**
   * Le passager entre dans ce bus en demandant une place assise. 
   * L'etat du passager est forcement dehors. 
   * Cette methode est appelee par Passager. 
   * @param le passager 
   */
    public void demanderPlaceAssise(Passager p)
    {

          p.accepterPlaceAssise();
          passagers[nbPassagers] = p;
          nbPassagers++;
          jaugeAssis.incrementer();
    }





   /**
   * Le passager entre dans ce bus en demandant une place debout. 
   * L'etat du passager est forcement dehors. 
   * Cette methode est appelee par passager. 
   * Elle change l'etat du passager. 
   * @param le passager
   **/
    public void demanderPlaceDebout(Passager p)
    {
          p.accepterPlaceDebout();
          passagers[nbPassagers] = p;
          nbPassagers++;
          jaugeDebout.incrementer();
    }





	/**
	* Fait sortir un passager du bus. Elle change l'etat du passager.
	* @param le passager avec un etat soit assis soit debout.
	**/
    public void demanderSortie(Passager p)
    {
	if(p.estDebout())
	    jaugeDebout.decrementer();
	else if (p.estAssis())
	    jaugeAssis.decrementer();

	p.accepterSortie();
        for(int i = 0 ; i < nbPassagers ; i++)
           if(passagers[i] == p){
              passagers[i] = passagers[nbPassagers-1] ;
              passagers[nbPassagers-1] = null ;
              nbPassagers--;
              break;
           }
    }




  /**
   * Cette méthode est heritée de la classe {@link java.lang.Object}.
   * Très utile pour le débogage, elle permet de fournir une 
   * chaîne de caractères correspondant à l'état d'un objet.
   * <p> Un code par défaut est définit dans 
   * {@link java.lang.Object#toString() la classe Object} 
   * Il faut adapter (redéfinir) le code de cette méthode à chaque classe.
   *
   * Pour les chaînes de cararctères, l'opérateur + correspond a la concaténation. 
   */
  @Override
   public String toString() {
       return "[arret:"+ numeroArret + ", assis:" + jaugeAssis +
          ", debout:" + jaugeDebout + "]";
    }

}
